package agg;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

import org.apache.commons.httpclient.HttpException;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import Community.fb.FacebookUser;
import Media.ui.ManageDevices;
import Media.ui.UIExtendable;

import com.google.code.facebookapi.FacebookException;
import com.google.code.facebookapi.schema.Album;
import com.google.code.facebookapi.schema.Photo;
import com.vladium.utils.timing.ITimer;
import com.vladium.utils.timing.TimerFactory;


/**
 * Runs the application. This is just a very ad-hoc solution at the moment to
 * let me quickly test/run the different components of the suite.
 * 
 * @author Hardeep
 */
public class Agg {
	public static Display display = new Display();
	private static HashSet<byte[]> bArrs = new HashSet<byte[]>();
	private static ITimer tf = TimerFactory.newTimer();
	
	public static void main(String[] args) {
		int runner = 0;
		
        switch (runner) {
        	case 0: doGUI(); break;
        	case 1: doFaceBook(); break;
        	case 2: doSpeedTest(); break;
        	case 3: 
        		class base {
        			public String name = "";
        		}
        		class big extends base {
        			public String value = "";
        		}
        		
        		big b = new big();
        		b.name = "test";
        		b.value = "value";
        		
        		base a = (base)b;
        		big c = (big)a;
        		
        		System.out.println("C Name: " + c.name);
        		System.out.println("C Value: " + c.value);
        	break;
        }
	}
	
	private static void doGUI() {
		UIExtendable ui = new ManageDevices();
		ui.createShell();
		Shell shell = ui.open();
		
		while( !shell.isDisposed() ) {
		  if(!display.readAndDispatch()) 
		  display.sleep();
		}
		display.dispose();
	}

	private static void doFaceBook() {
		FacebookUser fbUser;
		Scanner in = new Scanner(System.in);
		
		String user = "";
		String pass = "";
		
		// get user/pass to log into
		System.out.println("Facebook username? ");
		user = in.nextLine();
		System.out.println("Facebook password? ");
		pass = in.nextLine();
		
		try {
			fbUser = new FacebookUser(user, pass);
			List<Album> albums = fbUser.getAlbums();
			
			for ( Album a : albums ) {
				System.out.println("############## Album: " + a.getName());
				List<Photo> Pics = fbUser.getPhotos(a);
				for ( Photo p : Pics ) {
					System.out.println("\t" + p.getSrcBig());
				}
			}
		} catch (HttpException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FacebookException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private static void doSpeedTest() {
		speedTest();
		
		System.out.print("Running tests...");
		int run_times = 10;
		ArrayList<double[]> total_results = new ArrayList<double[]>();
		for (int i = 0; i <= run_times; i++) 
			total_results.add(speedTest_run(i));
		
		// calculate average
		double average_empty = 0;
		double average_1 = 0;
		double average_2 = 0;
		double average_3 = 0;
		
		double[] temp = {};
		for (int j = 0; j < total_results.size(); j++) {
			temp = total_results.get(j);
			average_empty += temp[0];
			average_1 += temp[1];
			average_2 += temp[2];
			average_3 += temp[3];
		}
		System.out.println("done.");
		
		System.out.println("----------------");
		System.out.println("Total Empty Run-time: " + average_empty + "ms");
		System.out.println("Total 1 Run-time: " + average_1 + "ms");
		System.out.println("Total 2 Run-time: " + average_2 + "ms");
		System.out.println("Total 3 Run-time: " + average_3 + "ms");
		System.out.println("----------------");
		System.out.println("Average Empty Run-time: " + average_empty / total_results.size() + "ms");
		System.out.println("Average 1 Run-time: " + average_1 / total_results.size() + "ms");
		System.out.println("Average 2 Run-time: " + average_2 / total_results.size() + "ms");
		System.out.println("Average 3 Run-time: " + average_3 / total_results.size() + "ms");
	}

	private static void speedTest() {
		int x = 100000;
		
		// generate X amount of random byte arrays:
		int len = 256; // length of strings
		int totalLen = 0;
		Random r = new Random();
		String s = "";
		
		System.out.println("------- speed test --------");
		System.out.println("Generating " + NumberFormat.getInstance().format(x) + " strings.");
		
		tf.start();
		for (int i = 0; i <= x; i++) {
			s = "";
			
			for (int j = 0; j <= len; j++)
				s += r.nextInt(9);
			
			totalLen += s.length();
			bArrs.add(s.getBytes());
		}
		tf.stop();
		System.out.println("Total number of characters: " + NumberFormat.getInstance().format(totalLen));
		System.out.println("Average chars per string: " + NumberFormat.getInstance().format(totalLen / x));
		System.out.println("String generation time: " + tf.getDuration());
		tf.reset();
	}
	
	private static double[] speedTest_run(int run_numer) {
		double[] results = {0,0,0,0};
		
		// first, lets see how long an empty loop takes to give us a control
		// basis
		tf.start();
		Iterator<byte[]> empty = bArrs.iterator();
		while ( empty.hasNext() ) {
			empty.next();
		}
		tf.stop();
		results[0] = tf.getDuration();
		tf.reset();
		
		try {
			Iterator<byte[]> toHexString = bArrs.iterator();
			
			tf.start();
			while ( toHexString.hasNext() ) {
				HexTools.toHexString(toHexString.next());
			}
			tf.stop();
			results[1] = tf.getDuration();
			tf.reset();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Iterator<byte[]> bufferToHex = bArrs.iterator();
		tf.start();
		while ( bufferToHex.hasNext() ) {
			HexTools.bufferToHex(bufferToHex.next());
		}
		tf.stop();
		results[2] = tf.getDuration();
		tf.reset();
		
		Iterator<byte[]> byteArrayToHexString = bArrs.iterator();
		tf.start();
		while ( byteArrayToHexString.hasNext() ) {
			HexTools.byteArrayToHexString(byteArrayToHexString.next());
		}
		tf.stop();
		results[3] = tf.getDuration();
		tf.reset();
		
		return results;
	}
}
